7.4 recover

在前面的章节我们讲过了panicdefer,在其他语言中还会有一个概念,那就是防崩溃的东西。

Go语言中同样具有这样的概念,那就是recover

recover主要用于在程序panic时进行恢复,保证程序不会崩溃掉。

本节代码存放目录为 lesson22

recover使用

recover都是与defer联合使用的,在上一节我们讲到了defer,现在我们再增加上协程,让案例更直观。如下代码所示:

func main() {
    deferPanic()

    go func() {
        for {
            fmt.Println("Running...")
            time.Sleep(time.Duration(1) * time.Second)
        }
    }()

    select {}
}

func deferPanic() {
    fmt.Printf("函数进入...\n")

    defer fmt.Println("函数结束,defer逻辑调用...")

    fmt.Printf("函数执行...\n")

    panic(errors.New("执行出错"))

    fmt.Printf("函数return...\n")

    return
}

执行上面的代码,结果输出如下:

函数进入...
函数执行...
函数结束,defer逻辑调用...
panic: 执行出错

goroutine 1 [running]:
main.deferPanic()
        /Users/xc/xcWork/YouCanGo/Code/YouCanGoCode/lesson22/lesson22.go:29 +0x151
main.main()
        /Users/xc/xcWork/YouCanGo/Code/YouCanGoCode/lesson22/lesson22.go:10 +0x25
exit status 2

通过结果输出,我们可以看到整个程序都已经崩溃了,协程也没有运行。下面我们增加recover进行查看,代码如下:

func deferPanic() {
    fmt.Printf("函数进入...\n")

    defer func() {
        if err := recover(); err != nil {
            fmt.Printf("recover err-> %v\n", err)
        }
    }()

    fmt.Printf("函数执行...\n")

    panic(errors.New("执行出错"))

    fmt.Printf("函数return...\n")

    return
}

在上面的代码中,我们去除了:

defer fmt.Println("函数结束,defer逻辑调用...")

增加了recover的使用:

defer func() {
    if err := recover(); err != nil {
        fmt.Printf("recover err-> %v\n", err)
    }
}()

此时我们再执行上面的代码,结果输出如下:

函数进入...
函数执行...
recover err-> 执行出错
Running...
Running...

从运行结果可以看出,程序panic之后被recover捕获到了,并且将程序进行了恢复,程序并没有崩溃。

综上所述,recover可以防止崩溃,进行程序的恢复,在实际的开发过程中,我们的主程序一般都需要具备recover功能,这样可以使我们的业务能够自恢复。

小结

recover主要用于捕获panic并进行程序恢复,与defer结合使用。

关于本节总结如下:

  • recover可以捕获到panic

  • recover可以使程序恢复

  • recoverdefer结合使用

  • 实际开发中我们的主程序应具备recover功能

results matching ""

    No results matching ""